package cn.edu.xmu.oomall.customer.controller;

import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.oomall.core.util.ResponseUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.customer.model.vo.*;
import cn.edu.xmu.oomall.customer.service.CustomerService;
import cn.edu.xmu.privilegegateway.annotation.aop.Audit;

import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import io.swagger.annotations.*;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

@RestController
@Slf4j
@RefreshScope
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class CustomerController {

    @Autowired
    private CustomerService customerService;
    @Autowired
    private HttpServletResponse httpServletResponse;

    /**
     * 修改返点,xcb
     */
    @PutMapping("/internal/addcustomerpoint/{id}")
    InternalReturnObject addCustomerPoint(@PathVariable("id") Long id, @RequestParam Long point){
        customerService.addCustomerPoint(id,point);
        return new InternalReturnObject();
    }


    /**
     * 获得买家所有状态
     * @return Returnobject(statelist)
     */
    @ApiOperation(value = "获得买家的所有状态")
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @GetMapping(value = "/customers/states")
    public Object getAllStates()
    {
        return Common.decorateReturnObject(customerService.getAllStates());
    }


    /**
     * 注册用户
     * @param vo
     * @param bindingResult
     * @return
     */
    @ApiOperation(value = "注册用户")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "body", dataType = "CustomerVo", name = "vo", value = "用户信息", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @PostMapping("/customers")
    public Object registerUser(@Validated @RequestBody CustomerVo vo,
                               BindingResult bindingResult)
    {
        Object o= Common.processFieldErrors(bindingResult,httpServletResponse);
        if(o!=null)
        {
            return o;
        }
        ReturnObject returnObject = customerService.registerUser(vo);
        if(returnObject.getData()==null)
            return Common.decorateReturnObject(returnObject);
        return new ResponseEntity(ResponseUtil.ok(returnObject.getData()), HttpStatus.CREATED);
    }


    @ApiOperation(value = "用户登录")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "body", dataType = "LoginCustomer", name = "vo", value = "登录信息", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @PostMapping("/login")
    public Object userLogin(@Validated @RequestBody LoginCustomer loginCustomer,
                            BindingResult bindingResult)
    {
        Object o= Common.processFieldErrors(bindingResult,httpServletResponse);
        if(o!=null)
        {
            return o;
        }
        ReturnObject returnObject = customerService.login(loginCustomer);
        if (returnObject.getCode().equals(ReturnNo.CUSTOMER_INVALID_ACCOUNT))
            return new ResponseEntity(ResponseUtil.fail(returnObject.getCode(), returnObject.getErrmsg()), HttpStatus.UNAUTHORIZED);
        if (returnObject.getCode().equals(ReturnNo.OK))
            return new ResponseEntity(ResponseUtil.ok(returnObject.getData()), HttpStatus.CREATED);
        if(returnObject.getCode().equals(ReturnNo.CUSTOMER_FORBIDDEN))
            return new ResponseEntity(ResponseUtil.fail(returnObject.getCode(), returnObject.getErrmsg()), HttpStatus.FORBIDDEN);
        return Common.decorateReturnObject(returnObject);
    }
    @ApiOperation(value = "用户登出")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit
    @GetMapping("/logout")
    public Object logout(@LoginUser Long userid)
    {

        return Common.decorateReturnObject(customerService.logout(userid));
    }
    /**
     * 用户查询信息
     * @param userid
     * @return
     */
    @ApiOperation(value = "用户查询自己信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit
    @GetMapping("/self")
    public Object getCustomerInfo(@LoginUser Long userid)
    {
        ReturnObject returnObject = customerService.getUserInfo(userid);
        return Common.decorateReturnObject(returnObject);
    }


    /**
     * 买家修改自己的信息
     * @param userId
     * @param vo
     * @param bindingResult
     * @return
     */
    @ApiOperation(value = "买家修改自己的信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(paramType = "body", dataType = "SimpleCustomerVo", name = "vo", value = "可修改的用户信息", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit
    @PutMapping("/self")
    public Object changeUserInfo(@LoginUser Long userId,
                                 @Validated @RequestBody SimpleCustomerVo vo,
                                 BindingResult bindingResult)
    {
        Object o= Common.processFieldErrors(bindingResult,httpServletResponse);
        if(o!=null)
        {
            return o;
        }
        return Common.decorateReturnObject(customerService.changeUserInfo(userId,vo));
    }


    @ApiOperation(value = "用户重置密码")
    @ApiImplicitParams(value={
                    @ApiImplicitParam(paramType = "body", dataType = "PasswordResetVo", name = "vo", value = "用户名", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @PutMapping("/password/reset")
    public Object ResetPassword(@Validated @RequestBody PasswordResetVo vo,
                                BindingResult bindingResult)
    {
        Object o = Common.processFieldErrors(bindingResult, httpServletResponse);
        if(null!=o){
            return o;
        }
        return Common.decorateReturnObject(customerService.ResetUserPassword(vo));
    }


    /**
     * 修改用户密码
     * @param vo
     * @param bindingResult
     * @return
     */
    @ApiOperation(value = "用户修改密码")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "body", dataType = "NewPasswordVo", name = "vo", value ="修改的密码", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @PutMapping("/password")
    public Object changePassword(@Validated @RequestBody NewPasswordVo vo,
                                 BindingResult bindingResult)
    {
        Object o= Common.processFieldErrors(bindingResult,httpServletResponse);
        if(o!=null)
        {
            return o;
        }
        return Common.decorateReturnObject(customerService.changeUserPassword(vo));
    }

    /**
     * 平台管理员查询所有用户列表
     * @param id
     * @param userName
     * @param email
     * @param mobile
     * @param page
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "平台管理员获取所有用户列表")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "shopid",required = true),
            @ApiImplicitParam(name = "userName",dataType = "String",value = "用户名",required = false),
            @ApiImplicitParam(name = "email",dataType = "String",value = "邮箱名",required = false),
            @ApiImplicitParam(name = "mobile",dataType = "String",value = "电话号码",required = false)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit(departName = "shops")
    @GetMapping("/shops/{id}/customers")
    public Object GetAllUsers(@PathVariable("id") Long id,
                              @RequestParam(name = "userName",required = false) String userName,
                              @RequestParam(name = "email",required = false) String email,
                              @RequestParam(name = "mobile",required = false) String mobile,
                              @RequestParam(name = "page",required = false) Integer page,
                              @RequestParam(name = "pageSize",required = false) Integer pageSize)
    {
        if(!id.equals(Long.valueOf(0)))
        {
            return Common.decorateReturnObject(new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE));
        }
        return Common.decorateReturnObject(customerService.getAllUserInfo(userName,email,mobile,page,pageSize));
    }


    /**
     * 平台管理员查看任意买家信息
     * @param shopId
     * @param userId
     * @return
     */
    @ApiOperation(value = "平台管理员查看任意买家信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "ShopId",dataType = "Integer",value = "shopid",required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "用户id",required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit(departName = "shops")
    @GetMapping("/shops/{shopId}/customers/{id}")
    public Object getUserById(@PathVariable("shopId") Long shopId,
                              @PathVariable("id") Long userId,
                            @LoginUser Long adminid)
    {
        if(adminid==null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        if(!shopId.equals(Long.valueOf(0)))
        {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        return Common.decorateReturnObject(customerService.getUserInfo(userId));
    }

    @GetMapping("/internal/shops/{shopId}/customers/{id}")
    public InternalReturnObject InternalGetUserById(@PathVariable("shopId") Long shopId,
                              @PathVariable("id") Long userId)
    {
        if(!shopId.equals(Long.valueOf(0)))
        {
            return new InternalReturnObject<>(ReturnNo.RESOURCE_ID_OUTSCOPE.getCode(), "操作的资源id不是自己的对象");
        }
        return new InternalReturnObject<>(customerService.getUserInfo(userId).getData());
    }

    /**
     * 平台管理员封禁买家
     * @param did
     * @param id
     * @return
     */
    @ApiOperation(value = "平台管理员封禁买家")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "did",dataType = "Integer",value = "shopid",required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "用户id",required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit(departName = "shops")
    @PutMapping("/shops/{did}/customers/{id}/ban")
    public Object banUser(@PathVariable("did") Long did,
                          @PathVariable("id") Long id,
                          @LoginUser Long userId,
                          @LoginName String userName)
    {
        if(!did.equals(Long.valueOf(0)))
        {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        return Common.decorateReturnObject(customerService.banUser(id,userId,userName));
    }

    /**
     * 平台管理员解禁买家
     * @param did
     * @param id
     * @return
     */
    @ApiOperation(value = "平台管理员解禁买家")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "did",dataType = "Integer",value = "shopid",required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "用户id",required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @Audit(departName = "shops")
    @PutMapping("/shops/{did}/customers/{id}/release")
    public Object releaseUser(@PathVariable("did") Long did,
                              @PathVariable("id") Long id,
                              @LoginUser Long modifierId,
                              @LoginName String modifierName)
    {
        if(!did.equals(Long.valueOf(0)))
        {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        return Common.decorateReturnObject(customerService.releaseUser(id,modifierId,modifierName));
    }

    /**
     * 减少用户积点
     * @param id
     * @param point
     * @return
     */
    @ApiOperation(value = "内部API:使用用户积点")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "point",dataType = "Integer",value = "积点数量",required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "用户id",required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @PutMapping("internal/customer/{id}/point")
    public Object usePoint(@PathVariable Long id,
                           @RequestParam Long point)
    {
        if(point<0)
        {
            return Common.decorateReturnObject(new ReturnObject(ReturnNo.STATENOTALLOW));
        }
        else
        {
            return Common.decorateReturnObject(customerService.usePoint(id, point));
        }

    }
    /**
     * 退回用户积点
     * @param id
     * @param point
     * @return
     */
    @ApiOperation(value = "内部API:退回用户积点")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "point",dataType = "Integer",value = "积点数量",required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "用户id",required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @PutMapping("internal/customer/{id}/point/refund")
    public Object refundPoint(@PathVariable Long id,
                           @RequestParam Long point)
    {
        if(point<0)
        {
            return Common.decorateReturnObject(new ReturnObject(ReturnNo.STATENOTALLOW));
        }
        else
        {
            return Common.decorateReturnObject(customerService.refundPoint(id, point));
        }
    }
    @ApiOperation(value = "内部API:根据ID查询顾客简易信息")
    @ApiImplicitParams(value={
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "用户token", required = true),
            @ApiImplicitParam(name = "id",dataType = "Integer",value = "用户id",required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "成功")
    })
    @GetMapping("internal/customer/{id}")
    public Object getCustomerById(@PathVariable Long id)
    {
        return Common.decorateReturnObject(customerService.getSimpleCustomerInfo(id));
    }
}
